<template>
  <div class="assessment-page">
    <el-card>
      <el-form :inline="true" :model="searchForm" class="search-form-container mb-6 bg-gray-50 p-4 rounded-lg shadow-sm">
        <div class="search-inputs-actions">
          <div class="flex items-center flex-wrap gap-x-4 gap-y-2">
            <el-form-item label="" class="mb-0">
              <el-input v-model="searchForm.name" placeholder="测评名称" style="width: 180px;" clearable />
            </el-form-item>
            <el-form-item label="" class="mb-0">
              <el-input v-model="searchForm.courseId" placeholder="课程ID" style="width: 150px;" clearable />
            </el-form-item>
            <el-form-item class="mb-0">
              <el-button @click="handleSearch" class="gradient-purple-blue-button">查询</el-button>
              <el-button @click="resetSearch" class="gradient-blue-cyan-button" style="margin-left: 8px;">重置</el-button>
            </el-form-item>
          </div>

          <div class="flex items-center gap-x-4">
            <el-button @click="openCreateDialog" class="gradient-blue-toggle-button">新增测评</el-button>
            <el-button @click="toggleView" class="gradient-blue-toggle-button">
              {{ isCardView ? '切换为列表' : '切换为卡片' }}
            </el-button>
          </div>
        </div>
      </el-form>

      <el-row :gutter="20" class="chart-section" style="margin-bottom: 20px;">
        <el-col :span="12">
          <el-card shadow="hover">
             <h3 style="margin-bottom: 15px;">各课程测评数量分布</h3>
            <v-chart class="chart" :option="courseChartOptions" autoresize />
          </el-card>
        </el-col>
        <el-col :span="12">
          <el-card shadow="hover">
            <h3 style="margin-bottom: 15px;">测评总分区间分布</h3>
            <v-chart class="chart" :option="scoreChartOptions" autoresize />
          </el-card>
        </el-col>
      </el-row>

      <div v-loading="loading">
        <template v-if="isCardView">
          <el-row :gutter="20" class="assessment-card-grid">
            <template v-if="examList.length > 0">
              <el-col :xs="24" :sm="12" :md="8" v-for="item in examList" :key="item.id">
                <el-card class="assessment-card">
                  <div class="assessment-card-content">
                    <h4 class="assessment-card-title" :title="item.name">{{ item.name }}</h4>
                    <p class="assessment-card-info"><span class="info-label">课程ID:</span> {{ item.courseId }}</p>
                    <p class="assessment-card-info"><span class="info-label">总分:</span> {{ item.totalScore }}</p>
                    <p class="assessment-card-info"><span class="info-label">时长:</span> {{ item.timeLimit }} 分钟</p>
                    <p class="assessment-card-info"><span class="info-label">创建于:</span> {{ dateFormatterForTable(null, null, item.createTime) }}</p>
                     <p class="assessment-card-info"><span class="info-label">文件:</span>
                       <a v-if="item.filePath" :href="getFileUrl(item.filePath)" target="_blank" class="file-link">{{ getFileName(item.filePath) }}</a>
                       <span v-else>无</span>
                     </p>
                  </div>
                  <div class="assessment-card-actions">
                    <el-button size="mini" @click="viewExam(item)">详情</el-button>
                    <el-button size="mini" @click="openEditDialog(item)">编辑</el-button>
                    <el-button size="mini" type="danger" @click="deleteExam(item)" class="light-red-button">删除</el-button>
                  </div>
                </el-card>
              </el-col>
            </template>
            <div v-else class="empty-data">
              <el-empty description="暂无测评，请新增或调整搜索条件"></el-empty>
            </div>
          </el-row>
        </template>

        <template v-else>
          <el-table :data="examList" border style="width: 100%; margin-top: 20px;">
             <el-table-column prop="id" label="ID" width="60" />
             <el-table-column prop="name" label="考试名称" />
             <el-table-column prop="courseId" label="课程ID" />
             <el-table-column prop="totalScore" label="总分" />
             <el-table-column prop="timeLimit" label="时长(分钟)" />
             <el-table-column prop="createTime" label="创建时间" :formatter="dateFormatterForTable" />
             <el-table-column label="文件路径">
               <template #default="{ row }">
                 <a v-if="row.filePath" :href="getFileUrl(row.filePath)" target="_blank">{{ getFileName(row.filePath) }}</a>
                 <span v-else>无</span>
               </template>
             </el-table-column>
             <el-table-column label="操作" width="220">
               <template #default="{ row }">
                 <el-button size="small" @click="viewExam(row)">详情</el-button>
                 <el-button size="small" @click="openEditDialog(row)">编辑</el-button>
                 <el-button size="small" type="danger" @click="deleteExam(row)" class="light-red-button">删除</el-button>
               </template>
             </el-table-column>
          </el-table>
        </template>
      </div>
    </el-card>

    <el-dialog
      v-model="dialogVisible"
      :title="dialogMode === 'create' ? '新增测评' : '编辑测评'"
      width="550px"
      :close-on-click-modal="false"
      @close="resetForm"
    >
      <el-form :model="form" :rules="rules" label-width="90px" ref="formRef">
        <el-form-item label="测评名称" prop="name">
          <el-input v-model="form.name" placeholder="请输入测评名称" />
        </el-form-item>
        <el-form-item label="课程ID" prop="courseId">
          <el-input v-model.number="form.courseId" type="number" placeholder="请输入所属课程ID" />
        </el-form-item>
        <el-form-item label="总分" prop="totalScore">
          <el-input v-model.number="form.totalScore" type="number" placeholder="请输入测评总分" />
        </el-form-item>
        <el-form-item label="时长(分钟)" prop="timeLimit">
          <el-input v-model.number="form.timeLimit" type="number" placeholder="请输入测评时长" />
        </el-form-item>
        <el-form-item label="创建时间" prop="createTime">
          <el-date-picker
            v-model="form.createTime"
            type="datetime"
            value-format="YYYY-MM-DD HH:mm:ss"
            style="width: 100%"
            placeholder="请选择创建时间"
          />
        </el-form-item>
        <el-form-item label="测评文件">
          <div v-if="dialogMode === 'edit' && form.filePath && !newFile" class="existing-file">
            <span>{{ getFileName(form.filePath) }}</span>
            <el-button link type="primary" @click="clearExistingFile" style="margin-left: 10px;">更换文件</el-button>
          </div>
          <el-upload
            v-else
            ref="uploadRef"
            :auto-upload="false"
            :show-file-list="true"
            :on-change="handleFileChange"
            :limit="1"
            accept=".pdf,.doc,.docx"
          >
            <el-button>选择文件</el-button>
            <template #tip>
              <div class="el-upload__tip">仅支持 pdf, doc, docx 格式。编辑时若不上传新文件，则保留原文件。</div>
            </template>
          </el-upload>
        </el-form-item>
      </el-form>
      <template #footer>
        <el-button @click="dialogVisible = false">取消</el-button>
        <el-button type="primary" @click="submitForm" :loading="isSubmitting">确定</el-button>
      </template>
    </el-dialog>

    <el-dialog v-model="detailVisible" title="测评详情" width="400px">
      <el-descriptions :column="1" border>
        <el-descriptions-item label="ID">{{ detailData.id }}</el-descriptions-item>
        <el-descriptions-item label="测评名称">{{ detailData.name }}</el-descriptions-item>
        <el-descriptions-item label="课程ID">{{ detailData.courseId }}</el-descriptions-item>
        <el-descriptions-item label="总分">{{ detailData.totalScore }}</el-descriptions-item>
        <el-descriptions-item label="时长(分钟)">{{ detailData.timeLimit }}</el-descriptions-item>
        <el-descriptions-item label="创建时间">{{ dateFormatterForTable(null, null, detailData.createTime) }}</el-descriptions-item>
        <el-descriptions-item label="文件路径">
          <template #default>
            <a v-if="detailData.filePath" :href="getFileUrl(detailData.filePath)" target="_blank">{{ getFileName(detailData.filePath) }}</a>
            <span v-else>无</span>
          </template>
        </el-descriptions-item>
      </el-descriptions>
      <template #footer>
        <el-button @click="detailVisible=false">关闭</el-button>
      </template>
    </el-dialog>
  </div>
</template>

<script setup>
import { ref, reactive, onMounted, watch } from 'vue';
import { ElMessage, ElMessageBox } from 'element-plus';
import assessmentService from '../../services/assessmentService';
import { FILE_BASE_URL } from '../../services/config';

// ECharts 相关引入
import { use } from 'echarts/core';
import { CanvasRenderer } from 'echarts/renderers';
import { PieChart, BarChart } from 'echarts/charts';
import { TitleComponent, TooltipComponent, LegendComponent, GridComponent } from 'echarts/components';
import VChart from 'vue-echarts';

use([ CanvasRenderer, PieChart, BarChart, TitleComponent, TooltipComponent, LegendComponent, GridComponent ]);

// --- 页面与列表状态 ---
const examList = ref([]);
const loading = ref(false);

// --- 新增：视图切换状态 ---
const isCardView = ref(true);

// --- 新增：搜索表单状态 ---
const searchForm = reactive({ name: '', courseId: '' });

// --- 图表状态 ---
const courseChartOptions = ref({});
const scoreChartOptions = ref({});

// --- 详情弹窗状态 ---
const detailVisible = ref(false);
const detailData = ref({});

// --- 新建/编辑弹窗状态 ---
const dialogVisible = ref(false);
const dialogMode = ref('create');
const isSubmitting = ref(false);
const formRef = ref();
const uploadRef = ref();
const newFile = ref(null);

const getDefaultForm = () => ({
  id: null,
  name: '',
  courseId: null,
  totalScore: null,
  timeLimit: null,
  createTime: '',
filePath: '',
});
const form = reactive(getDefaultForm());

const rules = reactive({
  name: [{ required: true, message: '请输入测评名称', trigger: 'blur' }],
  courseId: [{ required: true, message: '请输入课程ID', trigger: 'blur' }],
  totalScore: [{ required: true, message: '请输入总分', trigger: 'blur' }],
  timeLimit: [{ required: true, message: '请输入时长', trigger: 'blur' }],
  createTime: [{ required: true, message: '请选择创建时间', trigger: 'change' }],
});

// --- 数据加载与图表更新 ---
async function loadList(params = {}) {
  loading.value = true;
  try {
    const res = await assessmentService.getExamList(params);
    if (res.status === 0) {
      examList.value = res.data;
    } else {
      examList.value = [];
      ElMessage.error(res.message || '获取测评列表失败');
    }
  } catch (error) {
    examList.value = [];
    ElMessage.error('请求列表数据时发生错误');
  } finally {
    loading.value = false;
  }
}

onMounted(() => {
  loadList();
});

watch(examList, (newList) => {
  updateChartData(newList || []);
}, { deep: true });

function updateChartData(list) {
  // 各课程测评数量分布 - 柱状图
  const courseCounts = {};
  list.forEach(exam => {
    courseCounts[exam.courseId] = (courseCounts[exam.courseId] || 0) + 1;
  });
  const courseIds = Object.keys(courseCounts);
  const courseExamNumbers = Object.values(courseCounts);

  courseChartOptions.value = {
    tooltip: { trigger: 'axis', axisPointer: { type: 'shadow' } },
    grid: { left: '3%', right: '4%', bottom: '3%', containLabel: true },
    xAxis: { type: 'category', data: courseIds, axisLabel: { interval: 0, rotate: 30 }, name: '课程ID' },
    yAxis: { type: 'value', name: '测评数量' },
    series: [{ name: '测评数量', type: 'bar', data: courseExamNumbers, barWidth: '60%' }]
  };

  // 测评总分区间分布 - 饼图
  const scoreDistribution = [
    { name: '0-100分', value: 0 },
    { name: '101-120分', value: 0 },
    { name: '121-150分', value: 0 },
    { name: '>150分', value: 0 }
  ];
  list.forEach(exam => {
    const score = exam.totalScore;
    if (score <= 100) scoreDistribution[0].value++;
    else if (score <= 120) scoreDistribution[1].value++;
    else if (score <= 150) scoreDistribution[2].value++;
    else scoreDistribution[3].value++;
  });

  scoreChartOptions.value = {
    tooltip: { trigger: 'item', formatter: '{a} <br/>{b}: {c} ({d}%)' },
    legend: { orient: 'vertical', left: 'left', data: scoreDistribution.map(item => item.name) },
    series: [{
      name: '总分区间',
      type: 'pie',
      radius: '65%',
      center: ['60%', '50%'],
      data: scoreDistribution,
      emphasis: { itemStyle: { shadowBlur: 10, shadowOffsetX: 0, shadowColor: 'rgba(0, 0, 0, 0.5)' } }
    }]
  };
}

// --- 新增：搜索与重置方法 ---
function handleSearch() {
  const params = {};
  if (searchForm.name) {
    params.name = searchForm.name;
  }
  if (searchForm.courseId) {
    params.courseId = searchForm.courseId;
  }
  loadList(params);
}

function resetSearch() {
  searchForm.name = '';
  searchForm.courseId = '';
  loadList();
}

// --- 新增：视图切换方法 ---
const toggleView = () => {
  isCardView.value = !isCardView.value;
};


// --- 弹窗核心操作 ---
function resetForm() {
  Object.assign(form, getDefaultForm());
  newFile.value = null;
  if (uploadRef.value) {
    uploadRef.value.clearFiles();
  }
  if (formRef.value) {
    formRef.value.clearValidate();
  }
}

function openCreateDialog() {
  resetForm();
  dialogMode.value = 'create';
  dialogVisible.value = true;
}

function openEditDialog(row) {
  resetForm();
  dialogMode.value = 'edit';
  Object.assign(form, JSON.parse(JSON.stringify(row)));
  form.createTime = formatCellValueToPicker(row.createTime);
  dialogVisible.value = true;
}

function handleFileChange(uploadFile) {
  newFile.value = uploadFile.raw;
}

function clearExistingFile() {
  form.filePath = '';
}

async function submitForm() {
  if (!formRef.value) return;
  try {
    await formRef.value.validate();
  } catch (err) {
    return;
  }

  isSubmitting.value = true;

  const fd = new FormData();
  fd.append('name', form.name);
  fd.append('courseId', String(form.courseId));
  fd.append('totalScore', String(form.totalScore));
  fd.append('timeLimit', String(form.timeLimit));
  if (form.createTime) {
    fd.append('createTime', form.createTime.replace(' ', 'T'));
  } else {
    fd.append('createTime', '');
  }

  if (dialogMode.value === 'edit') {
    fd.append('id', form.id);
    if (newFile.value) {
      fd.append('file', newFile.value);
    } else if (form.filePath) {
      fd.append('filePath', form.filePath);
    }
  } else {
    if (newFile.value) {
      fd.append('file', newFile.value);
    }
  }

  try {
    let res;
    if (dialogMode.value === 'create') {
      res = await assessmentService.createExam(fd);
    } else {
      res = await assessmentService.updateExam(fd);
    }

    if (res.status === 0) {
      ElMessage.success(dialogMode.value === 'create' ? '新建成功' : '更新成功');
      dialogVisible.value = false;
      loadList(); // 重新加载列表以显示最新数据
    } else {
      ElMessage.error(res.message || '操作失败');
    }
  } catch (error) {
    console.error("Submit form error:", error);
    ElMessage.error('请求失败，请检查网络或联系管理员');
  } finally {
    isSubmitting.value = false;
  }
}

// --- 其他操作 ---
async function deleteExam(row) {
  try {
    await ElMessageBox.confirm('确定要删除该测评吗？', '提示', { type: 'warning' });
    const res = await assessmentService.deleteExam(row.id);
    if (res.status === 0) {
      ElMessage.success('删除成功');
      loadList(); // 重新加载列表
    } else {
      ElMessage.error(res.message || '删除失败');
    }
  } catch {
    // 用户取消操作
  }
}

async function viewExam(row) {
  try {
    const res = await assessmentService.getExam(row.id);
    if (res.status === 0) {
      detailData.value = res.data;
      detailVisible.value = true;
    } else {
      ElMessage.error(res.message || '获取详情失败');
    }
  } catch (error) {
    ElMessage.error('请求详情数据时发生错误');
  }
}

// --- 工具函数 ---
function getFileName(filePath) {
    if (typeof filePath === 'string' && filePath) {
        return filePath.split('/').pop();
    }
    return '';
}

function getFileUrl(filePath) {
  if (!filePath) return '';
  if (filePath.startsWith('http')) return filePath;
  return FILE_BASE_URL + filePath;
}

function formatCellValueToPicker(cellValue) {
  if (!cellValue) return '';
  
  let dateObj;
  try {
    if (Array.isArray(cellValue)) {
      const [y, m, d, hh, mm, ss] = cellValue;
      dateObj = new Date(y, (m || 1) - 1, d || 1, hh || 0, mm || 0, ss || 0);
    } else {
      dateObj = new Date(cellValue);
    }
    if (isNaN(dateObj.getTime())) {
      return '';
    }
  } catch (e) {
    return '';
  }
  
  const y = dateObj.getFullYear();
  const m = String(dateObj.getMonth() + 1).padStart(2, '0');
  const d = String(dateObj.getDate()).padStart(2, '0');
  const hh = String(dateObj.getHours()).padStart(2, '0');
  const mm = String(dateObj.getMinutes()).padStart(2, '0');
  const ss = String(dateObj.getSeconds()).padStart(2, '0');
  
  return `${y}-${m}-${d} ${hh}:${mm}:${ss}`;
}

function dateFormatterForTable(row, column, cellValue) {
  const formattedDate = formatCellValueToPicker(cellValue);
  if (formattedDate) {
    return formattedDate.slice(0, 16); // 表格中不显示秒
  }
  return '';
}
</script>

<style scoped>
/* 整体页面样式 */
.assessment-page {
  padding: 32px 24px;
  background: #f8f9fb;
}

/* 常用原子CSS类 */
.mb-6 { margin-bottom: 1.5rem; }
.flex { display: flex; }
.justify-between { justify-content: space-between; }
.items-center { align-items: center; }
.flex-wrap { flex-wrap: wrap; }
.gap-x-4 { column-gap: 1rem; }
.gap-y-2 { row-gap: 0.5rem; }

/* 搜索表单容器 */
.search-form-container {
  background-color: #f9fafb;
  padding: 1rem;
  border-radius: 0.5rem;
  box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
}

.search-inputs-actions {
  display: flex;
  justify-content: space-between;
  align-items: center;
  flex-wrap: wrap;
  width: 100%;
  gap: 10px;
}

.el-form-item.mb-0 {
  margin-bottom: 0 !important;
}

/* 图表区域 */
.chart-section {
  margin-top: 20px;
}
.chart {
  height: 300px;
}

/* --- 自定义渐变按钮样式 --- */
.gradient-purple-blue-button, .gradient-blue-cyan-button, .gradient-blue-toggle-button {
  color: #fff !important;
  border: none !important;
  transition: all 0.3s ease;
}
.gradient-purple-blue-button:hover, .gradient-blue-cyan-button:hover, .gradient-blue-toggle-button:hover,
.gradient-purple-blue-button:focus, .gradient-blue-cyan-button:focus, .gradient-blue-toggle-button:focus {
  opacity: 0.9;
  transform: translateY(-2px);
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
}
.gradient-purple-blue-button:active, .gradient-blue-cyan-button:active, .gradient-blue-toggle-button:active {
  transform: translateY(0);
  box-shadow: none;
}
.gradient-purple-blue-button { background-image: linear-gradient(to right, #8b5dbd, #548ee0) !important; }
.gradient-purple-blue-button:hover, .gradient-purple-blue-button:focus { background-image: linear-gradient(to right, #9d70d1, #69a7f3) !important; }
.gradient-purple-blue-button:active { background-image: linear-gradient(to right, #7b51aa, #4a7cc9) !important; }
.gradient-blue-cyan-button { background-image: linear-gradient(to right, #548ee0, #38afb5) !important; }
.gradient-blue-cyan-button:hover, .gradient-blue-cyan-button:focus { background-image: linear-gradient(to right, #69a7f3, #4fd3d8) !important; }
.gradient-blue-cyan-button:active { background-image: linear-gradient(to right, #4a7cc9, #2f969b) !important; }
.gradient-blue-toggle-button { background-image: linear-gradient(to right, #3f51b5, #2196f3) !important; }
.gradient-blue-toggle-button:hover, .gradient-blue-toggle-button:focus { background-image: linear-gradient(to right, #5c6bc0, #42a5f5) !important; }
.gradient-blue-toggle-button:active { background-image: linear-gradient(to right, #303f9f, #1976d2) !important; }

/* 自定义浅红色按钮 */
.light-red-button {
  background-color: #FEE2E2 !important;
  color: #EF4444 !important;
  border-color: #FEE2E2 !important;
}
.light-red-button:hover, .light-red-button:focus {
  background-color: #FECDCD !important;
  border-color: #FECDCD !important;
}
.light-red-button:active {
  background-color: #FBB0B0 !important;
  border-color: #FBB0B0 !important;
}

/* 测评卡片视图样式 */
.assessment-card-grid {
  display: flex;
  flex-wrap: wrap;
  gap: 20px 0; /* 卡片垂直间距，水平由Col的gutter控制 */
  margin-top: 20px;
  padding-bottom: 20px;
}

.assessment-card {
  height: 100%; /* 让卡片在同一行内等高 */
  min-height: 280px;
  border-radius: 8px;
  overflow: hidden;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
  transition: all 0.2s ease;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  background-color: #ffffff;
  border: 1px solid #e9e9e9;
}

.assessment-card:hover {
  transform: translateY(-2px);
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
}

.assessment-card-content {
  padding: 15px;
  flex-grow: 1;
  display: flex;
  flex-direction: column;
  gap: 8px; /* 调整内容行间距 */
}

.assessment-card-title {
  font-size: 1.1em;
  font-weight: bold;
  color: #333;
  margin-bottom: 10px;
  white-space: normal;
  overflow: hidden;
  text-overflow: ellipsis;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  line-height: 1.4;
  height: 2.8em; /* 限制标题高度为两行 */
}

.assessment-card-info {
  font-size: 0.9em;
  color: #666;
  margin: 0;
  line-height: 1.5;
}

.assessment-card-info .info-label {
  font-weight: 500;
  color: #444;
  margin-right: 5px;
}

.assessment-card-info .file-link {
  color: #409EFF;
  text-decoration: none;
}
.assessment-card-info .file-link:hover {
  text-decoration: underline;
}

.assessment-card-actions {
  padding: 10px 15px;
  border-top: 1px solid #f0f0f0;
  display: flex;
  justify-content: flex-end;
  gap: 8px;
  background-color: #fafafa;
}

.assessment-card-actions .el-button {
  min-width: unset;
  padding: 7px 12px;
  font-size: 0.85em;
}

.empty-data {
  width: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
  min-height: 200px;
}

/* 弹窗内已有文件样式 */
.existing-file {
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
  padding: 0 10px;
  background-color: #f5f7fa;
  border-radius: 4px;
  border: 1px solid #dcdfe6;
  height: 32px;
  line-height: 32px;
  color: #606266;
}

.el-upload__tip {
  color: #909399;
  font-size: 12px;
  line-height: 1.5;
}
</style>